/*
 * TowerYellowOne.java
 *
 * Created on December 14, 2007, 10:44 AM
 *
 * Copyright (C) 2007-2008  Hylke van der Schaaf
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, in version 3 of the License.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package hextd.tower;

import hextd.hex.Hex;
import hextd.creep.Creep;
import hextd.core.Context;
import hextd.util.Geometry;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;

/**
 *
 * @author hylke
 */
public class TowerYellowOne extends TowerBase {

	public static int price = 300;
	public static int damage = 1200;
	public static float range = 9f;
	//
	private Creep fireAt = null;
	private Creep.COLOR damageColor = Creep.COLOR.YELLOW;
	private int charge = 0;
	private int chargeMax = 40;
	//
	private Color transColor;
	private Stroke[] beam1Strokes;
	private Stroke[] beam2Strokes;
	private Stroke beam1Stroke;
	private Stroke beam2Stroke;
	private Color beam1Color;
	private Color beam2Color;
	private Shape[] pies;
	private Color line2Color;

	/** Creates a new instance of TowerYellowOne */
	public TowerYellowOne(Context context, Hex hex, int owner, int activateTick) {
		super(TowerFactory.type.yellowOne, price, damage, range, owner, activateTick);
		this.lineColor = new Color(220, 220, 0);
		this.line2Color = new Color(110, 110, 0);
		this.transColor = new Color(this.lineColor.getRed(), this.lineColor.getGreen(), this.lineColor.getBlue(), 100);
		this.beam1Color = new Color(this.lineColor.getRed(), this.lineColor.getGreen(), this.lineColor.getBlue(), 100);
		this.beam2Color = new Color(255, 255, 128);
		hexInfluence = 1;
		this.doInit(context, hex);
	}

	@Override
	public void runTick(int gameTime) {
		if (this.charge == 0) {
			// Find a target
			if (!this.lock) {
				this.fireAt = null;
			}
			Creep enemy = this.findEnemy(this.fireAt, false);
			this.fireAt = enemy;
			if (enemy != null) {
				this.charge++;
			}
		}
		if (this.charge > 0) {
			// Still a valid target?
			if (this.fireAt != null && this.fireAt.validTarget()) {
				this.charge++;
				if (this.charge >= this.chargeMax) {
					this.fireAt.doDamage(this.getOwner(), this.damageCurrent, this.damageColor);
					this.charge = 0;
				} else {
					if (beam1Strokes != null) {
						beam1Stroke = beam1Strokes[charge - 1];
						beam2Stroke = beam2Strokes[charge - 1];
					}
				}
			} else {
				this.charge = 0;
				this.fireAt = null;
			}
		}
	}

	@Override
	public String getStatusString() {
		String retString = "";
		retString += "<h1>Yellow Tower 1</h1>" +
				"<p>" +
				"<b>Level:</b> " + (1 + this.level) + "<br>\n" +
				"<b>Damage:</b> " + this.damageText + "<br>\n" +
				"<b>Range:</b> " + this.rangeText + "<br>" +
				"<b>Refire rate:</b> 0.5/s" +
				"</p>\n";
		return retString;
	}

	@Override
	public String getInfoString() {
		String retString = "";
		retString += "<h1>Yellow Tower 1</h1>" +
				"<p>" +
				"Basic tower with one strong laser that draws energy from the target for 2 seconds before firing. " +
				"<br>Strong against yellow enemies, very weak against blue enemies." +
				"</p>" +
				"<p>" +
				"<b>Price:</b> " + TowerYellowOne.form.format(TowerYellowOne.price) + "<br>" +
				"<b>Damage:</b> " + TowerYellowOne.form.format(this.damageCurrent) + "<br>" +
				"<b>Range:</b> " + TowerYellowOne.form.format(rangeCurrent) + "<br>" +
				"<b>Refire rate:</b> 0.5/s" +
				"</p>";
		return retString;
	}

	@Override
	protected void generateShapes() {
		float width = hexPaintWidth;
		float scale2 = 0.5f * this.paintScale;
		int shapeCount = 2;

		this.shapes = new Shape[shapeCount];

		float[][] points2 = Geometry.createHexCoords(this.paintScale);
		GeneralPath polyHex = Geometry.coordsToGeneralPath(points2, true);

		Area tower = new Area(polyHex);

		float[][] points1 = Geometry.createHexCoords(scale2);
		polyHex = Geometry.coordsToGeneralPath(points1, true);
		Area tempArea = new Area(polyHex);

		tower.subtract(tempArea);
		this.shapes[0] = tower;
		this.shapes[1] = new Ellipse2D.Float(-1.0f * strokeScale, -1.0f * strokeScale, 2.0f * strokeScale, 2.0f * strokeScale);

		this.shapeAction = new int[shapeCount];
		this.shapeAction[0] = 2;

		this.shapeColor = new Color[shapeCount];
		this.shapeColor[0] = this.lineColor;

		this.strokes = new Stroke[shapeCount];
		this.strokes[0] = new BasicStroke(2.0f * strokeScale, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);

		float max = this.chargeMax;
		this.pies = new Shape[this.chargeMax + 1];
		for (int i = 0; i < this.pies.length; i++) {
			this.pies[i] = new Arc2D.Float(-scale2, -scale2, scale2 * 2, scale2 * 2, 0, 360f * i / (max - 1), Arc2D.PIE);
		}

		this.beam1Strokes = new Stroke[this.chargeMax];
		this.beam2Strokes = new Stroke[this.chargeMax];
		for (int i = 0; i < this.chargeMax; i++) {
			this.beam1Strokes[i] = new BasicStroke(6.0f * (float) i / max * strokeScale, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
			this.beam2Strokes[i] = new BasicStroke(3.0f * (float) i / max * strokeScale, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
		}
	}

	@Override
	public void paint(Graphics2D g2, int gameTime) {
		Stroke defaultStroke = g2.getStroke();
		AffineTransform saveXform = g2.getTransform();

		g2.transform(atTranslate);

		g2.setColor(this.lineColor);
		g2.setStroke(this.strokes[0]);
		g2.fill(this.pies[this.charge]);

		g2.setColor(this.line2Color);
		g2.fill(this.shapes[0]);

		g2.setColor(this.lineColor);
		g2.draw(this.shapes[0]);
		g2.draw(this.shapes[1]);

		g2.setFont(this.levelFont);
		g2.drawString("" + (this.level + 1), this.levelLocation[0], this.levelLocation[1]);

		super.paintQueue(g2, gameTime);

		if (this.selected) {
			g2.setColor(this.rangeColor);
			g2.draw(this.rangeCircle);
		}

		g2.setTransform(saveXform);
		g2.setStroke(defaultStroke);

	}

	@Override
	public void paintEffects(Graphics2D g2, int gameTime) {
		Stroke defaultStroke = g2.getStroke();
		Creep target = fireAt;
		if (target != null && charge > 0) {
			float ex = target.getPaintX();
			float ey = target.getPaintY();
			g2.setColor(beam1Color);
			g2.setStroke(beam1Stroke);
			g2.draw(new Line2D.Float(xPaint, yPaint, ex, ey));
			g2.setColor(beam2Color);
			g2.setStroke(beam2Stroke);
			g2.draw(new Line2D.Float(xPaint, yPaint, ex, ey));
		}
		g2.setStroke(defaultStroke);
	}
}
